using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using Banshee.Base;
using Banshee.MediaEngine;
using Banshee.Sources;
using Banshee.Configuration.Schema;
using Banshee.Plugins;
using Banshee.Winforms;
using Banshee.Base.Winforms.Widgets;
using ComponentFactory.Krypton.Toolkit;

namespace Banshee
{
    public partial class MainForm : ComponentFactory.Krypton.Toolkit.KryptonForm
    {
        Banshee.Base.Gui.SourceView sourceView = null;
        private SeekSlider seek_slider = null;
        private StreamPositionLabel stream_position_label = null;
        public MainForm()
        {
            InitializeComponent();
            SuspendLayout();
            InitSystem();
            playlistModel.Source.Updated += new EventHandler(Source_Updated);
            playlistModel.Source.Cleared += new EventHandler(Source_Cleared);
            ResumeLayout();

        }
        private enum SearchTrackCriteria
        {
            Artist,
            Album,
            Genre
        }
        void Source_Cleared(object sender, EventArgs e)
        {
            this.UpdateStatusBar();
        }

        void Source_Updated(object sender, EventArgs e)
        {
            this.UpdateStatusBar();
        }
        void PlaceSearch()
        {
            searchEntry.Parent = mainHeader;
            searchEntry.Left = mainHeader.Width - searchEntry.Width - 5;
            searchEntry.Top = (mainHeader.Height - searchEntry.Height) / 2;
            searchEntry.Anchor = AnchorStyles.Top | AnchorStyles.Right; 
        }
        int sourceViewWidth = 235;
        void InitSystem()
        {
            LogCore.PrintEntries = true;
            Globals.Initialize();
            Globals.StartupInitializer.Run();
            LoadColumns();
            Globals.ShutdownRequested += new ShutdownRequestHandler(Globals_ShutdownRequested);
            SourceManager.ActiveSourceChanged += new SourceEventHandler(SourceManager_ActiveSourceChanged);
            trackSourceBindingSource.DataSource = playlistModel.Source;
            sourceView = new Banshee.Base.Gui.SourceView();
            libraryGroup.Panel.Controls.Add(sourceView);
            sourceView.Dock = DockStyle.Fill;
            PlayerEngineCore.StateChanged += new PlayerEngineStateHandler(PlayerEngineCore_StateChanged);
            PlayerEngineCore.EventChanged += new PlayerEngineEventHandler(PlayerEngineCore_EventChanged);
            Banshee.Winforms.Controls.ActiveUserEventsManager event_manager = new Banshee.Winforms.Controls.ActiveUserEventsManager();
            event_panel.Controls.Add(event_manager);
            event_manager.Dock = DockStyle.Fill;
            seek_slider = new SeekSlider();
            seek_slider.Dock = DockStyle.Fill;
            seek_slider.SetIdle();
            stream_position_label = new StreamPositionLabel(seek_slider);
            stream_position_label.Dock = DockStyle.Bottom;
            seekpanel.Controls.Add(stream_position_label);
            seekpanel.Controls.Add(seek_slider);
            playlistModel.Repeat = RepeatMode.All;
            this.Text = ApplicationLongName;
            PlaceSearch();
            TogglePlugPanel();
            KryptonManager.GlobalPaletteChanged += new EventHandler(KryptonManager_GlobalPaletteChanged);
            StartupComplete();
        }

        void KryptonManager_GlobalPaletteChanged(object sender, EventArgs e)
        {
            Color back = KryptonManager.CurrentGlobalPalette.GetBackColor1(PaletteBackStyle.PanelClient, PaletteState.Normal);
            seek_slider.ViewColor = back;
        }

        void PlayerEngineCore_EventChanged(object o, PlayerEngineEventArgs args)
        {
            switch (args.Event)
            {
                case PlayerEngineEvent.Iterate:
                    OnPlayerEngineTick();
                    break;
                case PlayerEngineEvent.Seek:
                    break;
                case PlayerEngineEvent.Error:
                    break;
                case PlayerEngineEvent.Metadata:
                    break;
                case PlayerEngineEvent.StartOfStream:
                    UpdateMetaDisplay();
                    OnPlayerEngineTick();
                    break;
                case PlayerEngineEvent.EndOfStream:
                    if (playlistModel.Repeat != RepeatMode.All || playlistModel.Repeat != RepeatMode.ErrorHalt)
                    {
                        playlistModel.ChangeDirection(true);
                        trackGrid.FirstDisplayedScrollingRowIndex = playlistModel.Current_index;
                    }
                    break;
                case PlayerEngineEvent.Volume:
                    break;
                case PlayerEngineEvent.Buffering:
                    break;
                case PlayerEngineEvent.TrackInfoUpdated:
                    break;
            }
        }
        public string ApplicationLongName
        {
            get { return Catalog.GetString("Banshee Music Player"); }
        }
        public void UpdateMetaDisplay()
        {
            TrackInfo track = PlayerEngineCore.CurrentTrack;

            if (track == null)
            {
                this.Text = ApplicationLongName;
                trackInfoHeader.Visible = false;
                cover_art_view.FileName = null;
                cover_art_view.BorderStyle = BorderStyle.None;
                //trackInfoHeader.Cover.Image = Properties.Resources.editor_cover_album;
                return;
            }

            trackInfoHeader.Artist = track.DisplayArtist;
            trackInfoHeader.Title = track.DisplayTitle;
            trackInfoHeader.Album = track.Album;
            trackInfoHeader.MoreInfoUri = track.MoreInfoUri != null ? track.MoreInfoUri.AbsoluteUri : null;
            trackInfoHeader.Visible = true;

            this.Text = track.DisplayTitle + ((track.Artist != null && track.Artist != String.Empty)
                ? (" (" + track.DisplayArtist + ")")
                : "");

            try
            {
                trackInfoHeader.FileName = track.CoverArtFileName;
                cover_art_view.FileName = track.CoverArtFileName;
                trackInfoHeader.Label = String.Format("{0} - {1}", track.DisplayArtist, track.DisplayAlbum);
                cover_art_view.Enabled = false;
            }
            catch (Exception)
            {
            }

        }
        void PlayerEngineCore_StateChanged(object o, PlayerEngineStateArgs args)
        {
            switch (args.State)
            {
                case PlayerEngineState.Idle:
                    break;
                case PlayerEngineState.Contacting:
                    break;
                case PlayerEngineState.Loaded:
                    break;
                case PlayerEngineState.Playing:
                    UpdateMetaDisplay();
                    break;
                case PlayerEngineState.Paused:
                    break;
                default:
                    break;
            }
        }

        void SourceManager_ActiveSourceChanged(SourceEventArgs args)
        {
            playlistModel.Source.Reload();
        }
        void StartupComplete()
        {
            Application.DoEvents();
            if (Globals.Library.IsLoaded)
            {
                Library_Reloaded(Globals.Library, new EventArgs());
            }
            else
            {
                Globals.Library.Reloaded += new EventHandler(Library_Reloaded);
            }
            
            Application.DoEvents();
        }

        void Library_Reloaded(object sender, EventArgs e)
        {
            if (this.Handle == IntPtr.Zero)
            {
                BeginInvoke((MethodInvoker)delegate()
                {
                    if (Globals.Library.Tracks.Count <= 0)
                    {
                        PromptForImport();
                    }
                    else
                    {
                        UpdateStatusBar();
                        sourceView.RefreshList();
                    }
                    
                });
            }
            else
            {
                if (Globals.Library.Tracks.Count <= 0)
                {
                    PromptForImport();
                }
                else
                {
                    SuspendLayout();
                    UpdateStatusBar();
                    sourceView.RefreshList();
                    ResumeLayout();
                }
            }

        }
        private void PromptForImport()
        {
            PromptForImport(true);
        }

        private void PromptForImport(bool startup)
        {
            bool show_dialog = System.Convert.ToBoolean(ImportSchema.ShowInitialImportDialog.Get());
            if (startup && !show_dialog)
            {
                return;
            }
            Banshee.Winforms.ImportDialog dialog = new Banshee.Winforms.ImportDialog();
            dialog.DoNotShowAgain = (bool)ImportSchema.ShowInitialImportDialog.Get();
            DialogResult dr = dialog.ShowDialog(this);
            if (dr != DialogResult.OK)
                return;
            else
            {
                IImportSource import_source = dialog.ActiveSource;
                if (import_source != null)
                {
                    import_source.Import();

                }
            }
            if (startup)
            {
                ImportSchema.ShowInitialImportDialog.Set(!dialog.DoNotShowAgain);
            }
        }
        bool Globals_ShutdownRequested()
        {
            //throw new Exception("The method or operation is not implemented.");
            return true;
        }
        private void MainForm_Load(object sender, EventArgs e)
        {
            SuspendLayout();

            SourceManager.SetActiveSource(LibrarySource.Instance);
            UpdateStatusBar();

            //Color back =  .GlobalPalette.GetBackColor1(ComponentFactory.Krypton.Toolkit.PaletteBackStyle.PanelClient, ComponentFactory.Krypton.Toolkit.PaletteState.Normal);
            //seek_slider.ViewColor = back;
            ResumeLayout();
            Banshee.Controls.SplashScreen.CloseForm();
            this.BringToFront();
        }
        
        private void MainForm_Resize(object sender, EventArgs e)
        {
            if (!libraryGroup.Collapsed)
            {
                mainSplitter.SplitterDistance = sourceViewWidth;
            }
        }
        private void UpdateStatusBar()
        {
                long count = playlistModel.Source.Tracks.Count;

                if (count == 0 && SourceManager.ActiveSource == null)
                {
                    LabelStatusBar.Text = ApplicationLongName;
                    return;
                }
                else if (count == 0)
                {
                    LabelStatusBar.Text = String.Empty;
                    return;
                }

                TimeSpan span = playlistModel.Source.TotalDuration;
                StringBuilder builder = new StringBuilder();

                builder.AppendFormat("{0} Items", count);
                builder.Append(", ");

                if (span.Days > 0)
                {
                    builder.AppendFormat("{0} days", span.Days);
                    builder.Append(", ");
                }

                if (span.Hours > 0)
                {
                    builder.AppendFormat("{0} hours", span.Hours);
                    builder.Append(", ");
                }

                builder.AppendFormat("{0} minutes", span.Minutes);
                builder.Append(", ");
                builder.AppendFormat("{0} seconds", span.Seconds);

                LabelStatusBar.Text = builder.ToString();
                mainHeader.Text = SourceManager.ActiveSource.Name;
        }
        private bool incrementedCurrentSongPlayCount;
        private void OnPlayerEngineTick()
        {
            seekpanel.BeginInvoke((MethodInvoker)delegate()
            {
                uint stream_length = PlayerEngineCore.Length;
                uint stream_position = PlayerEngineCore.Position;

                stream_position_label.IsContacting = false;
                seek_slider.CanSeek = PlayerEngineCore.CanSeek;
                Console.WriteLine(PlayerEngineCore.Position);
                seek_slider.Duration = stream_length;
                seek_slider.SeekValue = stream_position;
                seek_slider.Value = Convert.ToInt32(stream_position);
                
                if (PlayerEngineCore.CurrentTrack == null)
                {
                    return;
                }

                if (stream_length > 0 && PlayerEngineCore.CurrentTrack.Duration.TotalSeconds != (double)stream_length)
                {
                    PlayerEngineCore.CurrentTrack.Duration = new TimeSpan(stream_length * TimeSpan.TicksPerSecond);
                    PlayerEngineCore.CurrentTrack.Save();
                }

                if (stream_length > 0 && stream_position > stream_length / 2 && !incrementedCurrentSongPlayCount)
                {
                    PlayerEngineCore.CurrentTrack.IncrementPlayCount();
                    incrementedCurrentSongPlayCount = true;
                }
            });
        }
        private void trackGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex > 0)
            {
                string uri = trackGrid[uriDataGridViewTextBoxColumn.Index, e.RowIndex].Value.ToString();
                TrackInfo track = playlistModel.Source.Tracks[e.RowIndex];
                playlistModel.PlayTrack(track);
                playlistModel.Current_index = e.RowIndex;

            }
        }
        private int _widthLeftRight;
        private void libraryCollapseBtn_Click(object sender, EventArgs e)
        {

            this.mainSplitter.SuspendLayout();



            if (this.mainSplitter.FixedPanel == FixedPanel.None)
            {

                this.mainSplitter.FixedPanel = FixedPanel.Panel1;
                this.mainSplitter.IsSplitterFixed = true;

 
                _widthLeftRight = libraryGroup.Width;
  
                int newWidth = libraryGroup.PreferredSize.Height;
     
                this.mainSplitter.Panel1MinSize = newWidth;
                this.mainSplitter.SplitterDistance = newWidth;
   
                libraryGroup.HeaderPositionPrimary = VisualOrientation.Right;
                libraryGroup.ButtonSpecs[0].Edge = PaletteRelativeEdgeAlign.Near;
            }
            else
            {

                this.mainSplitter.FixedPanel = FixedPanel.None;
                this.mainSplitter.IsSplitterFixed = false;

                this.mainSplitter.Panel1MinSize = 100;

                this.mainSplitter.SplitterDistance = _widthLeftRight;
  
                libraryGroup.HeaderPositionPrimary = VisualOrientation.Top;
                libraryGroup.ButtonSpecs[0].Edge = PaletteRelativeEdgeAlign.Far;
            }
            this.mainSplitter.ResumeLayout();
        }
        int _heightUpDown;
        void TogglePlugPanel()
        {
            if (plugPlaySplitter.FixedPanel == FixedPanel.None)
            {
                plugPlaySplitter.FixedPanel = FixedPanel.Panel2;
                plugPlaySplitter.IsSplitterFixed = true;

                _heightUpDown = pluginGroup.Height;

                int newHeight = pluginGroup.PreferredSize.Height;
                plugPlaySplitter.Panel2MinSize = newHeight;
                plugPlaySplitter.SplitterDistance = plugPlaySplitter.Height;
            }
            else
            {
                plugPlaySplitter.FixedPanel = FixedPanel.None;
                plugPlaySplitter.IsSplitterFixed = false;
                plugPlaySplitter.Panel2MinSize = 100;
                plugPlaySplitter.SplitterDistance =
                plugPlaySplitter.Height - _heightUpDown - plugPlaySplitter.SplitterWidth;
            }

        }

        private void btnFwd_Click(object sender, EventArgs e)
        {
            playlistModel.ChangeDirection(true);
        }

        private void btnPrev_Click(object sender, EventArgs e)
        {
            playlistModel.ChangeDirection(false);
        }

        private void btnPlayPause_Click(object sender, EventArgs e)
        {
            if (PlayerEngineCore.CurrentState == PlayerEngineState.Playing)
            {
                PlayerEngineCore.Pause();
            }
            else if (PlayerEngineCore.CurrentState == PlayerEngineState.Paused || PlayerEngineCore.CurrentState == PlayerEngineState.Idle)
            {
                PlayerEngineCore.Play();
            }
        }
        public void LoadColumns()
        {
            for (int i = 0; i < trackGrid.Columns.Count; i++)
            {
                DataGridViewColumn col = trackGrid.Columns[i];

                if (col.HeaderText == "Title")
                    col.Visible = TitleVisibleSchema.Get();
                else if (col.HeaderText == "Artist")
                    col.Visible = ArtistVisibleSchema.Get();
                else if (col.HeaderText == "Album")
                    col.Visible = AlbumVisibleSchema.Get();
                else if (col.HeaderText == "Genre")
                    col.Visible = GenreVisibleSchema.Get();
                else if (col.HeaderText == "Time")
                    col.Visible = TimeVisibleSchema.Get();
                else if (col.HeaderText == "Year")
                    col.Visible = YearVisibleSchema.Get();
                else if (col.HeaderText == "Track")
                    col.Visible = TrackVisibleSchema.Get();
                else if (col.HeaderText == "Last Played")
                    col.Visible = LastPlayVisibleSchema.Get();
                else if (col.HeaderText == "Rating")
                    col.Visible = RatingVisibleSchema.Get();
                else if (col.HeaderText == "Plays")
                    col.Visible = PlayCountVisibleSchema.Get();


            }
        }
        #region Column Schemas
        public static Banshee.Configuration.SchemaEntry<bool> year_schema = new Banshee.Configuration.SchemaEntry<bool>(
        "view_columns", "yearvisible",
        false,
        "Visiblity",
        "Visibility of Year column"
        );
        protected Banshee.Configuration.SchemaEntry<bool> YearVisibleSchema
        {
            get { return year_schema; }
        }
        public static Banshee.Configuration.SchemaEntry<bool> title_schema = new Banshee.Configuration.SchemaEntry<bool>(
        "view_columns", "titlevisible",
        true,
        "Visiblity",
        "Visibility of Title column"
        );
        protected Banshee.Configuration.SchemaEntry<bool> TitleVisibleSchema
        {
            get { return title_schema; }
        }
        public static Banshee.Configuration.SchemaEntry<bool> artist_schema = new Banshee.Configuration.SchemaEntry<bool>(
        "view_columns", "artistvisible",
        true,
        "Visiblity",
        "Visibility of Artist column"
        );
        protected Banshee.Configuration.SchemaEntry<bool> ArtistVisibleSchema
        {
            get { return artist_schema; }
        }
        public static Banshee.Configuration.SchemaEntry<bool> album_schema = new Banshee.Configuration.SchemaEntry<bool>(
        "view_columns", "albumvisible",
        true,
        "Visiblity",
        "Visibility of Album column"
        );
        protected Banshee.Configuration.SchemaEntry<bool> AlbumVisibleSchema
        {
            get { return album_schema; }
        }
        public static Banshee.Configuration.SchemaEntry<bool> genre_schema = new Banshee.Configuration.SchemaEntry<bool>(
        "view_columns", "genrevisible",
        false,
        "Visiblity",
        "Visibility of Genre column"
        );
        protected Banshee.Configuration.SchemaEntry<bool> GenreVisibleSchema
        {
            get { return genre_schema; }
        }
        public static Banshee.Configuration.SchemaEntry<bool> tracknumber_schema = new Banshee.Configuration.SchemaEntry<bool>(
        "view_columns", "tracknumbervisible",
        true,
        "Visiblity",
        "Visibility of Track Number column"
        );
        protected Banshee.Configuration.SchemaEntry<bool> TrackVisibleSchema
        {
            get { return tracknumber_schema; }
        }
        public static Banshee.Configuration.SchemaEntry<bool> time_schema = new Banshee.Configuration.SchemaEntry<bool>(
        "view_columns", "durationvisible",
        true,
        "Visiblity",
        "Visibility of Duration column"
        );
        protected Banshee.Configuration.SchemaEntry<bool> TimeVisibleSchema
        {
            get { return time_schema; }
        }
        public static Banshee.Configuration.SchemaEntry<bool> lastplay_schema = new Banshee.Configuration.SchemaEntry<bool>(
        "view_columns", "lastplayvisible",
        false,
        "Visiblity",
        "Visibility of Track Number column"
        );
        protected Banshee.Configuration.SchemaEntry<bool> LastPlayVisibleSchema
        {
            get { return lastplay_schema; }
        }
        public static Banshee.Configuration.SchemaEntry<bool> playcount_schema = new Banshee.Configuration.SchemaEntry<bool>(
        "view_columns", "playcountvisible",
        false,
        "Visiblity",
        "Visibility of Play Count column"
        );
        protected Banshee.Configuration.SchemaEntry<bool> PlayCountVisibleSchema
        {
            get { return playcount_schema; }
        }
        public static Banshee.Configuration.SchemaEntry<bool> rating_schema = new Banshee.Configuration.SchemaEntry<bool>(
        "view_columns", "ratingvisible",
        false,
        "Visiblity",
        "Visibility of Rating column"
        );
        protected Banshee.Configuration.SchemaEntry<bool> RatingVisibleSchema
        {
            get { return rating_schema; }
        }
        #endregion

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
        TrackInfo PathTreeInfo(string path)
        {
            TrackInfo pathtrackinfo = null;
            foreach (TrackInfo track in SourceManager.ActiveSource.Tracks)
            {
                if (track.Uri.ToString() == path)
                {
                    pathtrackinfo = track;
                    break;
                }
            }
            return pathtrackinfo;
        }
        public IList<TrackInfo> SelectedTrackInfoMultiple
        {
            get
            {
                if (trackGrid.SelectedRows.Count == 0)
                {
                    return null;
                }

                List<TrackInfo> list = new List<TrackInfo>();

                foreach (DataGridViewRow row in trackGrid.SelectedRows)
                {
                    string uri = row.Cells[uriDataGridViewTextBoxColumn.Index].Value.ToString();
                    list.Add(PathTreeInfo(uri));
                }

                return list;
            }
        }
        private void SearchBySelectedTrack(SearchTrackCriteria criteria)
        {
            TrackInfo track = playlistModel.Selected_track;
            if (track == null)
            {
                return;
            }

            // suspend the search functionality (for performance reasons)
            suspendSearch = true;

            switch (criteria)
            {
                case SearchTrackCriteria.Album:
                    this.searchEntry.Field = Catalog.GetString("Album Title");
                    searchEntry.Query = track.Album;
                    break;
                case SearchTrackCriteria.Artist:
                    searchEntry.Field = Catalog.GetString("Artist Name");
                    searchEntry.Query = track.Artist;
                    break;
                case SearchTrackCriteria.Genre:
                    searchEntry.Field = Catalog.GetString("Genre");
                    searchEntry.Query = track.Genre;
                    break;
            } suspendSearch = false;
            OnSimpleSearch(this, null);

        }
        private bool suspendSearch;
        private void OnSimpleSearch(object o, EventArgs args)
        {
            //Cornel - I found the BackgroundWorker gives me the most responsive UI
            UpdateViewName(SourceManager.ActiveSource, "Searching...");
            SourceManager.ActiveSource.FilterField = searchEntry.Field;
            SourceManager.ActiveSource.FilterQuery = searchEntry.Query;
            Source source = SourceManager.ActiveSource;
            Source searchResult = new PlaylistSource();
            if (SourceManager.ActiveSource.HandlesSearch)
            {
                return;
            }

            if (suspendSearch)
            {
                return;
            }
            if (!searchEntry.IsQueryAvailable)
            {
                playlistModel.Source.Reload();
                return;
            }
            lock (SourceManager.ActiveSource.TracksMutex)
            {
                foreach (TrackInfo track in SourceManager.ActiveSource.Tracks)
                {
                    try
                    {
                        if (DoesTrackMatchSearch(track))
                        {
                            searchResult.AddTrack(track);
                        }
                    }
                    catch (Exception)
                    {
                        continue;
                    }
                }
                playlistModel.Source.SetCustomSource(searchResult);
            }
        }
        private void UpdateViewName(Source source, string info)
        {

            this.mainHeader.Text = string.Format("{0} {1}", source.Name, info);
        }
        private bool DoesTrackMatchSearch(TrackInfo ti)
        {
            if (!searchEntry.IsQueryAvailable)
            {
                return false;
            }

            string query = searchEntry.Query;
            string field = searchEntry.Field;
            string[] matches;

            if (field == Catalog.GetString("Artist Name"))
            {
                matches = new string[] { ti.Artist };
            }
            else if (field == Catalog.GetString("Song Name"))
            {
                matches = new string[] { ti.Title };
            }
            else if (field == Catalog.GetString("Album Title"))
            {
                matches = new string[] { ti.Album };
            }
            else if (field == Catalog.GetString("Genre"))
            {
                matches = new string[] { ti.Genre };
            }
            else if (field == Catalog.GetString("Year"))
            {
                matches = new string[] { ti.Year.ToString() };
            }
            else
            {
                matches = new string[] {
                    ti.Artist,
                    ti.Album,
                    ti.Title,
                    ti.Genre,
                    ti.Year.ToString()
                };
            }

            List<string> words_include = new List<string>();
            List<string> words_exclude = new List<string>();

            Array.ForEach<string>(Regex.Split(query, @"\s+"), delegate(string word)
            {
                bool exclude = word.StartsWith("-");
                if (exclude && word.Length > 1)
                {
                    words_exclude.Add(word.Substring(1));
                }
                else if (!exclude)
                {
                    words_include.Add(word);
                }
            });

            foreach (string word in words_exclude)
            {
                foreach (string match in matches)
                {
                    if (match == null || match == String.Empty)
                    {
                        continue;
                    }

                    if (StringUtil.RelaxedIndexOf(match, word) >= 0)
                    {
                        return false;
                    }
                }
            }

            bool found;

            foreach (string word in words_include)
            {
                found = false;

                foreach (string match in matches)
                {
                    if (match == null || match == string.Empty)
                    {
                        continue;
                    }

                    if (StringUtil.RelaxedIndexOf(match, word) >= 0)
                    {
                        found = true;
                        break;
                    }
                }

                if (!found)
                {
                    return false;
                }
            }

            return true;
        }
        private void song_properties_button_Click(object sender, EventArgs e)
        {
            Banshee.Base.Gui.Dialogs.TrackEditor propEdit = new Banshee.Base.Gui.Dialogs.TrackEditor(SelectedTrackInfoMultiple);
            propEdit.ShowDialog(this);
        }

        private void searchEntry_Changed(object sender, EventArgs e)
        {
            OnSimpleSearch(this, null);
            UpdateViewName(SourceManager.ActiveSource, "Searching");
        }
    }
}